package com.lovepick.util;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo.State;
import android.net.Uri;
import android.os.Environment;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;

import com.baidu.mapapi.GeoPoint;
import com.lovepick.GlobalApp;
import com.lovepick.bean.MsgItem;
import com.lovepick.bean.MsgListItem;
import com.lovepick.bean.Order;
import com.lovepick.bean.OrderInfo;
import com.lovepick.database.MsgDbManager;
import com.lovepick.database.MsgListDbManager;

/**
 * @author Liutong
 */
public class BaseUtils
{
	private static final String BASE_TAG = "BaseUtils";

	public static void exit(Activity activity)
	{
		activity.finish();
	}

	public static void showToast(Context context, String message)
	{
		Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
	}

	public static void showToast(Context context, int resId)
	{
		// TODO Auto-generated method stub
		Toast.makeText(context, resId, Toast.LENGTH_SHORT).show();
	}

	/**
	 * 检测系统网络状态
	 *
	 * @param context
	 * @return 移动或WIFI其中之一开启则返回true, 二者均关闭则返回false.
	 */
	public static boolean getNetworkState()
	{
		boolean state = false;
		ConnectivityManager manager = (ConnectivityManager) GlobalApp.getInstance()
				.getSystemService(Context.CONNECTIVITY_SERVICE);

		State mobile = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();
		Log.i(BASE_TAG, "mobile network:" + mobile.toString());
		State wifi = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();
		Log.i(BASE_TAG, "WIFI network:" + wifi.toString());

		if (mobile.equals(State.CONNECTED) || wifi.equals(State.CONNECTED))
		{
			state = true;
		}
		else
		{
			state = false;
		}

		return state;
	}

	/**
	 * 检测系统GPS状态
	 *
	 * @param context
	 * @return GPS开启返回true, 关闭则返回false.
	 */
	public static boolean getGpsState()
	{
		boolean gpsState = Settings.Secure.isLocationProviderEnabled(
				GlobalApp.getInstance().getContentResolver(), LocationManager.GPS_PROVIDER);
		Log.i(BASE_TAG, "GPS:" + gpsState);

		return gpsState;
	}

	/**
	 * 根据给定的格式检测字符串是否是符合该格式的日期时间
	 *
	 * @param date
	 *            待检测日期时间字符串
	 * @param format
	 *            检测格式
	 * @return 符合检测格式返回true, 否则false.
	 */
	public static boolean isDate(String date, String pattern)
	{
		SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
		dateFormat.setLenient(false);
		try
		{
			dateFormat.parse(date);
			return true;
		}
		catch (Exception e)
		{
			// TODO: handle exception
			Log.i(BASE_TAG, "checkDate:" + e.getMessage());
			return false;
		}
	}

	/**
	 * 检测给定字符串是否符合Email格式
	 *
	 * @param email
	 *            待检测字符串
	 * @return 符合Email格式返回true, 否则false.
	 */
	public static boolean isEmail(String email)
	{
		Pattern pattern = Pattern.compile(Constant.REGE_EMAIL);
		Matcher matcher = pattern.matcher(email);
		return matcher.matches();
	}

	/**
	 * 检测给定字符串是否为手机电话号码
	 *
	 * @param mobileNum
	 *            待检测字符串
	 * @return 为手机号码返回true, 否则false.
	 */
	public static boolean isMobileNum(String mobileNum)
	{
		Pattern pattern = Pattern.compile(Constant.REGE_MOBILENUM2);
		Matcher matcher = pattern.matcher(mobileNum);
		return matcher.matches();
	}

	/**
	 * Check whether the specified string is a numeric.
	 *
	 * @param num
	 *            string that need to be checked.
	 * @return true if the string is a numeric, false otherwise.
	 */
	public static boolean isNumeric(String num)
	{
		try
		{
			Integer.parseInt(num);
			return true;
		}
		catch (Exception e)
		{
			// TODO: handle exception
			Log.i(BASE_TAG, "checkNumeric:" + e.getMessage());
			return false;
		}
	}

	/**
	 * 判断给定字符串是否空白串. 空白串是指由空格、制表符、回车符、换行符组成的字符串.
	 *
	 * @param input
	 *            待检测字符串
	 * @return boolean 若输入字符串为null或空字符串，返回true
	 */
	public static boolean isEmptyString(String input)
	{
		if ((input == null) || "".equals(input))
		{
			return true;
		}

		for (int i = 0; i < input.length(); i++)
		{
			char c = input.charAt(i);
			if ((c != ' ') && (c != '\t') && (c != '\r') && (c != '\n'))
			{
				return false;
			}
		}
		return true;
	}

	public static boolean isUsername(String username)
	{
		Pattern pattern = Pattern.compile(Constant.REGE_USERNAME);
		Matcher matcher = pattern.matcher(username);
		return matcher.matches();
	}

	public static void callPhone(Context context, String phone)
	{
		Uri uri = Uri.parse("tel:" + phone);
        Intent intent = new Intent(Intent.ACTION_CALL, uri);
        context.startActivity(intent);
	}

	/**
	 * 解析由服务器返回的订单数据
	 *
	 * @param json	订单数据
	 * @param isFromRelease	是否是发布订单后返回的
	 * @return
	 * 		<ul>
	 * 		<li>解析成功: 订单数据数组</li>
	 * 		<li>解析失败: null</li>
	 * 		</ul>
	 */
	public static List<Order> getOrders(String json, boolean isFromRelease)
	{
		Log.i(BASE_TAG, "---getOrders---");
		List<Order> orders = null;
		try
		{
			orders = new ArrayList<Order>();
			JSONArray ja = new JSONArray(json);

			for (int i = 0; i < ja.length(); i++)
			{

				JSONObject jo = ja.getJSONObject(i);
				Order order = _getOrder(jo);
				orders.add(order);
			}

			// 如果是发布订单后服务器返回的数据, 则最后一项是刚才发布的订单的信息,
			// 将这一项保存之后从数组中删除.
			if (isFromRelease)
			{
				Log.i(BASE_TAG, "## 返回的数据是发布路线后推荐的订单 ##");
				Order myOrder = orders.get(orders.size() - 1);
				GlobalApp.getInstance().saveCurrentOrder(myOrder);
				orders.remove(orders.size() - 1);
			}
		}
		catch (JSONException e)
		{
			// TODO: handle exception
			orders = null;
			Log.i(BASE_TAG, "JSON解析异常!");
			e.printStackTrace();
		}
		return orders;
	}

	public static List<Order> getOrdersSimple(String json)
	{
		Log.i(BASE_TAG, "---getOrdersSimple---");
		List<Order> orders = null;
		try
		{
			orders = new ArrayList<Order>();
			JSONArray ja = new JSONArray(json);

			for (int i = 0; i < ja.length(); i++)
			{

				JSONObject jo = ja.getJSONObject(i);
				Order order = _getOrderSimple(jo);
				orders.add(order);
			}
		}
		catch (JSONException e)
		{
			// TODO: handle exception
			orders = null;
			Log.i(BASE_TAG, "JSON解析异常!");
			e.printStackTrace();
		}
		return orders;
	}

	public static Order getOrderDetail(String json)
	{
		Log.i(BASE_TAG, "---getOrderDetail---");
		Order order = null;
		try
		{
			JSONObject jo = new JSONObject(json);
			order = _getOrder(jo);
		}
		catch (JSONException e)
		{
			// TODO Auto-generated catch block
			Log.i(BASE_TAG, "JSON解析异常!");
			e.printStackTrace();
			order = null;
		}

		return order;
	}

	private static Order _getOrder(JSONObject jo) throws JSONException
	{
		Log.i(BASE_TAG, "---_getOrder---");
		Order order = new Order();
		order.setOrderID(jo.getInt(Order.ORDER_ID));
		order.setUserID(jo.getInt(Order.MEM_ID));
		order.setNickName(jo.getString(Order.NICKNAME));
		order.setGoTime(jo.getString(Order.GOTIME));
		order.setSrc(jo.getString(Order.SRC));
		order.setSlat(jo.getDouble(Order.SLAT));
		order.setSlng(jo.getDouble(Order.SLNG));
		order.setDest(jo.getString(Order.DEST));
		order.setDlat(jo.getDouble(Order.DLAT));
		order.setDlng(jo.getDouble(Order.DLNG));
		order.setMoney(jo.getInt(Order.MONEY));
		order.setOffset(jo.getInt(Order.OFFSET));
		order.setState(jo.getString(Order.STATE));
		order.setCount(jo.getInt(Order.COUNT));
		order.setPhone(jo.getString(Order.PHONE));

		List<GeoPoint> gPoints = null;
		if (jo.has(Order.POINTS))
		{
			JSONArray points = jo.getJSONArray(Order.POINTS);
			gPoints = new ArrayList<GeoPoint>();
			Log.i(BASE_TAG, "---添加" + points.length() + "个路径点信息---");
			for (int j = 0; j < points.length(); j++)
			{
				JSONObject tmp = points.getJSONObject(j);
				GeoPoint gPoint = new GeoPoint((int)(tmp.getDouble(Order.LAT)*1E6),
						(int)(tmp.getDouble(Order.LNG)*1E6));
				gPoints.add(gPoint);
			}
		}
		order.setPoints(gPoints);
		return order;
	}

	private static Order _getOrderSimple(JSONObject jo) throws JSONException
	{
		Order order = new Order();
		order.setOrderID(jo.getInt(Order.ORDER_ID));
		//order.setUserID(jo.getInt(Order.MEM_ID));
		//order.setNickName(jo.getString(Order.NICKNAME));
		order.setGoTime(jo.getString(Order.GOTIME));
		order.setSrc(jo.getString(Order.SRC));
		//order.setSlat(jo.getDouble(Order.SLAT));
		//order.setSlng(jo.getDouble(Order.SLNG));
		order.setDest(jo.getString(Order.DEST));
		//order.setDlat(jo.getDouble(Order.DLAT));
		//order.setDlng(jo.getDouble(Order.DLNG));
		order.setMoney(jo.getInt(Order.MONEY));
		//order.setOffset(jo.getInt(Order.OFFSET));
		order.setState(jo.getString(Order.STATE));
		order.setCount(jo.getInt(Order.COUNT));

		return order;
	}

	/**
	 * 解析司机查看拼车乘客时返回的数据, 或者乘客查看已完成的订单详情时的数据。
	 * @param json
	 * @return
	 */
	public static List<OrderInfo> getOrderInfos(String json)
	{
		Log.i(BASE_TAG, "---getOrderInfos---");
		List<OrderInfo> orders = null;
		try
		{
			orders = new ArrayList<OrderInfo>();
			JSONArray ja = new JSONArray(json);

			for (int i = 0; i < ja.length(); i++)
			{
				JSONObject jo = ja.getJSONObject(i);
				OrderInfo order = new OrderInfo();
				order.setPassengerName(jo.getString(OrderInfo.PASSENGER_NAME));
				order.setRouteID(jo.getInt(OrderInfo.ROUTE_ID));
				order.setDriverName(jo.getString(OrderInfo.DRIVER_NAME));
				order.setOrderID(jo.getInt(OrderInfo.ORDER_ID));
				order.setMoney(jo.getInt(OrderInfo.MONEY));
				order.setCount(jo.getInt(OrderInfo.COUNT));
				order.setFreeCount(jo.getInt(OrderInfo.FREE_COUNT));
				order.setState(jo.getString(OrderInfo.STATE));
				order.setPaID(jo.getInt(OrderInfo.PA_ID));
				order.setPaPhone(jo.getString(OrderInfo.PA_PHONE));
				order.setDrID(jo.getInt(OrderInfo.DR_ID));
				order.setDrPhone(jo.getString(OrderInfo.DR_PHONE));

				orders.add(order);
			}
		}
		catch (JSONException e)
		{
			// TODO: handle exception
			orders = null;
			Log.i(BASE_TAG, "JSON解析异常!");
			e.printStackTrace();
		}
		return orders;
	}

	/**
	 * 解析从服务器获取的新消息(json字符串)并存入数据库
	 *
	 * @param result
	 * @param currentUser
	 * @return
	 */
	public static Map<String, Object> saveNewMsgsForNotify(String result, int currentUser)
	{
		Log.i(BASE_TAG, "-----saveNewMsgsForNotify-----");
		MsgListDbManager msgListDbManager = null;
		MsgDbManager msgDbManager = null;
		Map<String, Object> notify = null;

		try
		{
			JSONObject jo = new JSONObject(result);
			int lastID = jo.getInt("last_id");
			GlobalApp.getInstance().setLastID(lastID);
			JSONArray jsonArray = jo.getJSONArray("messages");

			msgListDbManager = new MsgListDbManager();
			msgDbManager = new MsgDbManager();
			notify = new HashMap<String, Object>();

			switch (jsonArray.length())
			{
				case 1:
					// 只有一个用户发来消息
					notify.put("flag", 0);
					break;

				default:
					// 有多个用户发来消息
					notify.put("flag", 1);
					break;
			}

			int totalNum = 0;
			String users = "";
			String lastMsg = "";
			boolean isCurrentOnly = false;

			for (int i = 0; i < jsonArray.length(); i++)
			{
				//Log.i(BASE_TAG, "###消息写入数据库###");
				MsgListItem msgListItem = new MsgListItem();
				JSONObject jsonObject = jsonArray.getJSONObject(i);

				String nickName = jsonObject.getString("nickname");
				msgListItem.setNickName(nickName);

				int userID = jsonObject.getInt("id");
				msgListItem.setUserID(userID);

				if (jsonArray.length() == 1)
				{
					notify.put("user_id", userID);
				}

				if (userID != currentUser)
				{
					if (i != jsonArray.length()-1)
					{
						users += nickName + ", ";
					}
					else
					{
						users += nickName;
					}
				}

				if (userID==currentUser && jsonArray.length()==1)
				{
					// 只有一个用户发来消息, 而此用户是当前正在聊天用户
					isCurrentOnly = true;
				}

				JSONArray msgs = jsonObject.getJSONArray("msg_list");

				JSONObject tmp = null;
				for (int j = 0; j < msgs.length(); j++)
				{
					tmp = msgs.getJSONObject(j);

					MsgItem msgItem = new MsgItem();
					msgItem.setContent(tmp.getString("message"));
					//msgItem.setDate(getSimpleDate(tmp.getString("date")));
					msgItem.setDate(tmp.getString("date"));
					msgItem.setMsgType(MsgType.RECEIVE);

					msgDbManager.addMsg(userID, msgItem);
				}

				totalNum += msgs.length();
				lastMsg = tmp.getString("message");

				msgListItem.setLastMsg(tmp.getString("message"));
				msgListItem.setLastDate(tmp.getString("date"));
				msgListItem.setCount(msgs.length());
				msgListItem.setHasNew((currentUser == userID) ? 0 : 1);

				if (msgListDbManager.hasUser(userID))
				{
					msgListDbManager.updateMsgListItem(msgListItem);
				}
				else
				{
					msgListDbManager.addMsgListItem(msgListItem);
				}
			}

			if (isCurrentOnly || jsonArray.length()==0)
			{
				// 如果只有一个用户发来消息并且此用户是当前正在聊天用户
				// 清空之前记录的信息, 此时notify为空
				// 或者没有新消息, 清空
				notify.clear();
			}
			else
			{
				notify.put("nick_names", users);
				notify.put("number", totalNum);
				notify.put("last_msg", lastMsg);
			}

			Log.i(BASE_TAG, notify.toString());
		}
		catch (JSONException e)
		{
			// TODO Auto-generated catch block
			Log.i(BASE_TAG, "JSON解析异常!");
			e.printStackTrace();
			notify = null;
		}

		return notify;
	}

	/**
	 * 解析从服务器获取的新消息(json字符串)并存入数据库
	 * @param result		从服务器获取消息时的返回结果
	 * @param currentUser	当前聊天用户ID, 没有则为-1
	 * @return				有新消息返回true, 否则false
	 */
	public static boolean saveNewMsgs(String result, int currentUser)
	{
		Log.i(BASE_TAG, "-----saveNewMsgs-----");
		MsgListDbManager msgListDbManager = null;
		MsgDbManager msgDbManager = null;
		boolean hasNewMsgs = false;

		try
		{
			JSONObject jo = new JSONObject(result);
			int lastID = jo.getInt("last_id");
			GlobalApp.getInstance().setLastID(lastID);
			JSONArray jsonArray = jo.getJSONArray("messages");

			msgListDbManager = new MsgListDbManager();
			msgDbManager = new MsgDbManager();

			for (int i = 0; i < jsonArray.length(); i++)
			{
				//Log.i(BASE_TAG, "###消息写入数据库###");
				hasNewMsgs = true;

				MsgListItem msgListItem = new MsgListItem();
				JSONObject jsonObject = jsonArray.getJSONObject(i);

				String nickName = jsonObject.getString("nickname");
				msgListItem.setNickName(nickName);

				int userID = jsonObject.getInt("id");
				msgListItem.setUserID(userID);

				JSONArray msgs = jsonObject.getJSONArray("msg_list");

				JSONObject tmp = null;
				for (int j = 0; j < msgs.length(); j++)
				{
					tmp = msgs.getJSONObject(j);

					MsgItem msgItem = new MsgItem();
					msgItem.setContent(tmp.getString("message"));
					//msgItem.setDate(getSimpleDate(tmp.getString("date")));
					msgItem.setDate(tmp.getString("date"));
					msgItem.setMsgType(MsgType.RECEIVE);

					msgDbManager.addMsg(userID, msgItem);
				}

				msgListItem.setLastMsg(tmp.getString("message"));
				msgListItem.setLastDate(tmp.getString("date"));
				msgListItem.setCount(msgs.length());
				msgListItem.setHasNew((currentUser == userID) ? 0 : 1);

				if (msgListDbManager.hasUser(userID))
				{
					msgListDbManager.updateMsgListItem(msgListItem);
				}
				else
				{
					msgListDbManager.addMsgListItem(msgListItem);
				}
			}
		}
		catch (JSONException e)
		{
			// TODO Auto-generated catch block
			Log.i(BASE_TAG, "JSON解析异常!");
			e.printStackTrace();
			hasNewMsgs = false;
		}

		return hasNewMsgs;
	}

	/**
	 * 获取系统当前时间
	 *
	 * @return 返回当前系统时间对应的字符串
	 */
	public static String getCurrentDate()
	{
		Log.i(BASE_TAG, "-----获取系统当前时间-----");
		Calendar c = Calendar.getInstance();
		//SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm");
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String datetime = sdf.format(c.getTime());
		Log.i(BASE_TAG, datetime);

		return datetime;
	}

	/**
	 * 检测SD卡是否可写
	 *
	 * @return
	 */
	public static boolean isExternalWritable()
	{
		boolean isWritable = false;
		String state = Environment.getExternalStorageState();

		if (Environment.MEDIA_MOUNTED.equals(state))
		{
			isWritable = true;
		}
		else
		{
			isWritable = false;
		}

		return isWritable;
	}

	public static boolean saveAvatar(final String fileName, Bitmap bitmap)
	{
		Log.i(BASE_TAG, "-----save files-----");
		boolean isSuccess = false;
		boolean isWritable = isExternalWritable();
		File file = null;

		if (isWritable)
		{
			String dir = GlobalApp.getInstance().getExternalFilesDir(null).getParent();
			String path = dir + "/avatar/";

			File avatarDir = new File(path);
			if (!(avatarDir.exists()))
			{
				avatarDir.mkdir();
			}
			file = new File(path + fileName);
			Log.i(BASE_TAG, "###file=###" + file.toString());
			try
			{
				BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
				bitmap.compress(CompressFormat.PNG, 80, bos);
				bos.flush();
				bos.close();
				isSuccess = true;
				Log.i(BASE_TAG, "保存头像成功");
			}
			catch (FileNotFoundException e)
			{
				// TODO Auto-generated catch block
				Log.i(BASE_TAG, "FileNotFoundException");
				e.printStackTrace();
				isSuccess = false;
			}
			catch (IOException e)
			{
				// TODO Auto-generated catch block
				Log.i(BASE_TAG, "IOException");
				e.printStackTrace();
				isSuccess = false;
			}
		}

		return isSuccess;
	}

	/**
	 * 从本地读取用户头像<br>
	 *
	 * @param fileName	头像文件名(即用户昵称)
	 * @return
	 * 		<ul>
	 * 		<li>若本地保存了用户头像, 返回该头像的Bitmap</li>
	 * 		<li>若本地未保存用户头像, 返回null</li>
	 * 		</ul>
	 */
	public static Bitmap getAvatarFromLocal(String fileName)
	{
		Log.i(BASE_TAG, "---getAvatarFromLocal---");
		Bitmap bitmap = null;
		if (isExternalWritable())
		{
			String pathName = GlobalApp.getInstance().getExternalFilesDir(null).getParent() + "/avatar/" + fileName;
			bitmap = BitmapFactory.decodeFile(pathName);
		}
		return bitmap;
	}

	/**
	 * 简化时间显示格式;<br>
	 * yyyy-MM-dd HH:mm:ss --> MM-dd HH:mm
	 *
	 * @param datesString	yyyy-MM-dd HH:mm:ss
	 * @return				MM-dd HH:mm
	 */
	public static String getSimpleDate(String datesString)
	{
		//Log.i(BASE_TAG, "-----getSimpleDate-----");
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = null;
		String result = null;
		try
		{
			date = format.parse(datesString);
			SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm");
			result = sdf.format(date);
			//Log.i(BASE_TAG, datesString + " ---> " + result);

		}
		catch (ParseException e)
		{
			// TODO Auto-generated catch block
			Log.i(BASE_TAG, "日期转换异常");
			e.printStackTrace();
			result = null;
		}
		return result;

	}

	/**
	 * 检测在内部存储目录(data/data/$pakagename/files)中是否存在指定文件
	 *
	 * @param fileName	待查找文件名
	 * @return	存在返回true, 否则false.
	 */
	public static boolean hasInternalFile(String fileName)
	{
		File file = new File(GlobalApp.getInstance().getFilesDir().getPath() + fileName);

		return file.exists();
	}
}
